package com.wolfeyes.framework.aspect;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import com.wolfeyes.system.service.SysLogService;
//import com.bootdo.domain.po.system.UserTokenDO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.wolfeyes.common.annotation.SysLog;
//import com.wolfeyes.system.mapper.SysLogMapper;
import com.wolfeyes.system.domain.entity.SysLogDO;
import com.wolfeyes.common.utils.network.http.HttpContextUtils;
import com.wolfeyes.common.utils.network.ip.IpUtils;
import com.wolfeyes.common.utils.network.jsonbean.JSONUtils;
import com.wolfeyes.common.utils.network.web.ToolUtils;
import com.wolfeyes.framework.springsecurity.utils.SecurityUtils;
//import com.wolfeyes.utils.common.shiro.ShiroUtils;
//import com.wolfeyes.domain.po.system.UserDO;
import com.wolfeyes.system.domain.SysUser;


/**
 * @title web系统日志入库落盘（AOP切面类）
 * @projectName film
 * @className SysLogAspect.java
 * @author yanyljava
 * @email yanyljava@qq.com
 * @date 2018-07-04 15:53:58
 * @version 1.0.0
 */
@Aspect
//此处注解不能少
@Component
public class SysLogAspect {
	
    private static final Logger logger = LoggerFactory.getLogger(SysLogAspect.class);

    @Autowired
    SysLogService sysLogService;


    /**
     * 参考常见问题FAQ文档：配置多个aop:pointcut
     * @title 针对自定义注解@SysLog来定义切面的切点入口
     * @description AOP事务切入点-配置织入点
     * @methodName doSysLogPointCut()
     * @author yanyljava
     * @since 2017年07月09日下午5:37:39
     * @createTime 2018年07月09日 下午17:04:13
     */
    @Pointcut("@annotation(com.wolfeyes.common.annotation.SysLog)")
    public void doSysLogPointCut() {
    	
    	// 开始切入
    	logger.info("Spring Framework AOP 事务aspectjweaver-V1.8.13开始切入");
    	
    }

    @Around("doSysLogPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
    	
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = point.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //异步保存日志
        saveLog(point, time);
        
        return result;
    }

    void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
    	
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLogDO sysLog = new SysLogDO();
        SysLog syslog = method.getAnnotation(SysLog.class);
        
        if (syslog != null) {
            // 注解上的描述
            sysLog.setOperation(syslog.value());
        }
        
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        
        // 请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSONUtils.beanToJson(args[0]).substring(0, 4999);
            sysLog.setParams(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        // 快速获取当前请求对象request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 获取request作用域
        //HttpServletRequest request = ToolUtils.getRequest();
        
        //获取客户端IP地址，如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = IpUtils.getIpAddr(request);
        
        // 设置IP地址
        sysLog.setIp(ip);
        
        // 获取浏览器以及版本号
        Map<String, String> osAndBrowserInfo = ToolUtils.getOsAndBrowserInfo(request);
        // 浏览器以及版本号
        sysLog.setBrowser(osAndBrowserInfo.get("browser"));
        // 操作系统
        sysLog.setOs(osAndBrowserInfo.get("os"));
        
        // 用户名
        // 当前登录的用户信息
        //UserDO currUser = ShiroUtils.getUser();
        SysUser currUser = SecurityUtils.getCustomizeUserDetails().getUser();
        
        // 判断非空
        if (currUser == null) {
        	
            if (null != sysLog.getParams()) {
                sysLog.setUserId(-1L);
                sysLog.setUsername(sysLog.getParams());
            } else {
                sysLog.setUserId(-1L);
                sysLog.setUsername("获取用户信息为空");
            }
            
        } else {
        	
            //sysLog.setUserId(ShiroUtils.getUserId());
        	sysLog.setUserId(SecurityUtils.getCustomizeUserDetails().getUser().getUserId());
            //sysLog.setUsername(ShiroUtils.getUser().getUsername());
        	sysLog.setUsername(SecurityUtils.getUsername());
        }
        
        sysLog.setTime((int) time);
        
        // 系统当前时间
        Date date = new Date();
        sysLog.setCreateTime(date);
        
        // 保存系统日志
        //this.sysLogService.save(sysLog);
    }
    
}
